import re
from django.contrib.auth import get_user_model
from rest_framework import serializers
from core.base_pay.pay_serializers import BasePaySerializers
from .models import OrderRecord, ZXUser
from .client import ZXClient, zx_auth
from finance_c2c.local_settings import ONLINE
from finance_c2c.settings import REGEX_MOBILE
from core.tools.models import ShortMsg
from apps.user_operation.models import LevelDesc
from apps.user_operation.utils import jwt_payload_handler
from rest_framework_jwt.settings import api_settings
from apps.supply_order.models import Company
from core.tools.func_utils import FuncUtils

jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
UserModel = get_user_model()

zx_client = ZXClient()


class PaySerializers(BasePaySerializers):
    payType = (("app", "app支付"), ("pc", "pc"), ("h5", "h5"),)
    pay_type = serializers.ChoiceField(label="支付类型", choices=payType, allow_blank=False, allow_null=False,
                                       required=True)

    def create(self, validated_data):
        frontEndUrl = validated_data["redirect_url"]
        if hasattr(self, "czb_order_instance"):
            amountGun = self.czb_order_instance.amountGun
            payment = self.czb_order_instance.payment
            goodsInf = "加油订单#已享%s元优惠#" % "%.2f" % (amountGun - payment)
            payment = str(int(payment * 100))
            czb_order_instance = self.czb_order_instance
            czb_order_instance.pay_type = 6
            # 当没创建订单号的时候再创建
            if not czb_order_instance.out_trade_no:
                out_trade_no = FuncUtils().unique_value
                czb_order_instance.out_trade_no = out_trade_no
                print("zx create pay not out_trade_no", out_trade_no)
            else:
                out_trade_no = czb_order_instance.out_trade_no
                print("zx create pay has out_trade_no", out_trade_no)
            czb_order_instance.save()
        else:
            raise serializers.ValidationError("购物中信没上")
        params, response = zx_client.create_order(frontEndUrl, payment, out_trade_no, goodsInf=goodsInf)
        msgBody = params.get("msgBody")
        originMerId = msgBody.get("originMerId")
        requestTimestamp = msgBody.get("originTranTime")
        goodsAmount = msgBody.get("goodsAmount")
        srcReserve = "czb"
        record_data = {
            "originMerId": originMerId,
            "requestTimestamp": requestTimestamp,
            "out_trade_no": out_trade_no,
            "goodsAmount": goodsAmount,
            "srcReserve": srcReserve,
            "totalAmount": payment,
        }
        try:
            instance = OrderRecord.objects.get(out_trade_no=out_trade_no)
            instance.requestTimestamp = requestTimestamp  # 更新下支付时间
            instance.save()
        except Exception as e:
            print(e, "OrderRecord already exists")
            instance = OrderRecord.objects.create(**record_data)
        if instance.status == "TRADE_SUCCESS":
            raise serializers.ValidationError("此订单已经支付成功")
        pay_type = validated_data["pay_type"]
        if ONLINE:
            url_dict = {
                "h5": "https://s.creditcard.ecitic.com/citiccard/payweb/index.html#/orderDetail",
                "app": "https://s.creditcard.ecitic.com/citiccard/payweb/index.html#/middleHandler",
                "pc": "https://s.creditcard.ecitic.com/citiccard/cashierpc/offlineOrder.html",
            }
        else:
            url_dict = {
                "h5": "https://e.test.bank.ecitic.com/citiccard/payweb/index.html#/orderDetail",
                "app": "https://e.test.bank.ecitic.com/citiccard/payweb/index.html#/middleHandler",
                "pc": "https://e.test.bank.ecitic.com/citiccard/payweb/cashier-pc/offlineOrder.html"
            }
        url = url_dict.get(pay_type)
        msgBody = response.get("msgBody")
        instance = instance.update_response(**msgBody)
        url += "?resultUrl=%s&token=%s" % (frontEndUrl, instance.orderKey)
        setattr(self, 'pay_url', url)
        return instance


class ZxUserSerializers(serializers.Serializer):
    code = serializers.CharField(write_only=True, required=True, label="临时临牌cod")

    def validate(self, attrs):
        self.create(attrs)
        return attrs

    def create(self, validated_data):
        code = validated_data.pop("code")
        token_response = zx_auth.get_token(code)
        accessToken = token_response.get("accessToken")
        print(accessToken, "zhongxinaccessToken")
        if not accessToken:
            print(token_response.get("resultDesc"))
            raise serializers.ValidationError(token_response.get("resultDesc"))
        openid_response = zx_auth.get_openid(accessToken)
        zx_user_id = openid_response.get("openId")
        print(zx_user_id, "ssssssssssszx_user_id")
        if not zx_user_id:
            print(openid_response.get("resultDesc"))
            raise serializers.ValidationError(openid_response.get("resultDesc"))
        zx_user_info, created = ZXUser.objects.get_or_create(zx_user_id=zx_user_id)
        if hasattr(zx_user_info, "userprofile"):
            user = zx_user_info.userprofile
            print(user.mobile, 'mobile')
            payload = jwt_payload_handler(self, user)
            token = jwt_encode_handler(payload)
            setattr(self, 'object', {"user": user, "token": token})
        else:
            setattr(self, 'object', {"openid": zx_user_id})
        print(zx_user_id, "zx_user_id")
        return zx_user_info


# 中信登录注册
class MyLoginSerializer(serializers.Serializer):
    mobile = serializers.CharField(label="手机号", write_only=True, max_length=11, min_length=11, help_text="手机号",
                                   required=True, error_messages={
            "required": "手机号为必填项",
            "blank": "账号不能为空",
            "max_length": "账号过长",
            "min_length": "账号过短"
        })
    code = serializers.CharField(label="验证码", write_only=True, max_length=4, min_length=4, help_text="验证码",
                                 required=True, error_messages={
            "required": "手机号为必填项",
            "blank": "验证码不能为空",
            "max_length": "验证码过长",
            "min_length": "验证码过短"
        })
    openid_e = serializers.CharField(label="openid", write_only=True, required=False, allow_null=True,
                                     allow_blank=True)

    def validate_openid_e(self, openid):
        if openid:
            openid = openid.replace(" ", "+")
            print(openid, "validate_openid_e1111")
            zx_user_q = ZXUser.objects.filter(zx_user_id=openid)
            if zx_user_q.exists():
                return zx_user_q.first()
            else:
                openid = "+" + openid
                print(openid, "validate_openid_e2222")
                zx_user_q = ZXUser.objects.filter(zx_user_id=openid)
                if zx_user_q.exists():
                    return zx_user_q.first()
                else:
                    raise serializers.ValidationError("传入的openid错误")
        else:
            raise serializers.ValidationError("中信授权登录openid错误")

    def validate_mobile(self, mobile):
        if re.match(REGEX_MOBILE, mobile):
            return mobile
        else:
            raise serializers.ValidationError("手机号不合法")

    def validate_code(self, code):
        mobile = self.initial_data["mobile"]
        openid_e = self.initial_data["openid_e"]
        print(mobile, code, openid_e, "zhongxinvalidate_codeinfo")
        info = ShortMsg.objects.filter(code=code, tel=mobile)
        if info.exists():
            info_obj = info.first()
            if info_obj.status:
                info_obj.status = False
                info_obj.save()
                return code
            else:
                raise serializers.ValidationError("验证码已被使用过了")
        else:
            raise serializers.ValidationError("验证码不正确")

    def create(self, validated_data):
        mobile = validated_data["mobile"]
        try:
            user = UserModel.objects.get(mobile=mobile)
        except UserModel.DoesNotExist as e:
            user = UserModel.objects.create(
                mobile=mobile,
                level=LevelDesc.objects.get(level=1),
                username=mobile,
                company=Company.objects.get(sign="zxyh")
            )
        user.zx_user = validated_data["openid_e"]
        user.save()
        return user

    def update(self, instance, validated_data):
        pass

    def validate(self, attrs):
        user = self.create(attrs)
        payload = jwt_payload_handler(self, user)
        token = jwt_encode_handler(payload)
        setattr(self, 'object', {"user": user, "token": token})
        return {
            'token': token,
            'user': user
        }

    class Meta:
        fields = ("mobile", "code", "openid_e")
